#ifndef __LS_TRACE_COMMON_H__
#define __LS_TRACE_COMMON_H__

#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <assert.h>

#define LS_NONE "\033[m"
#define RED "\033[0;32;31m"
#define LIGHT_RED "\033[1;31m"
#define GREEN "\033[0;32;32m"
#define LIGHT_GREEN "\033[1;32m"
#define BLUE "\033[0;32;34m"
#define LIGHT_BLUE "\033[1;34m"
#define DARY_GRAY "\033[1;30m"
#define CYAN "\033[0;36m"
#define LIGHT_CYAN "\033[1;36m"
#define PURPLE "\033[0;35m"
#define LIGHT_PURPLE "\033[1;35m"
#define BROWN "\033[0;33m"
#define YELLOW "\033[1;33m"
#define LIGHT_GRAY "\033[0;37m"
#define WHITE "\033[1;37m"

#ifndef DBG_TAG
#define DBG_TAG ""
#endif


/* 调试等级 */
typedef enum lsLOG_LEVEL_E{
	LS_ASSERT =0,
	LS_LOG_NONE,
    LS_LOG_ERROR,
    LS_LOG_FAILED,
    LS_LOG_INFO,
    LS_LOG_DEBUG,
}LOG_LEVEL_E;

extern void LS_Trace(unsigned char loglevel,const char* _szColor, const char* _szPrefix, const char* _szFile, unsigned int _u32Line, const char* _szFunction, const char* _szFmt, ...);

// #define LS_TRACE_FAILED(...)   printf(LIGHT_RED"[" DBG_TAG "] " __VA_ARGS__);printf(LS_NONE"\r\n")
// #define LS_TRACE_INFO(...)     printf(YELLOW"[" DBG_TAG "] " __VA_ARGS__);printf(LS_NONE"\r\n")
// #define LS_TRACE_DEBUG(...)    printf(GREEN"[" DBG_TAG "] " __VA_ARGS__);printf(LS_NONE"\r\n")
// #define LS_TRACE_ERROR(...)    printf(RED"[" DBG_TAG "] "  __VA_ARGS__ );printf(LS_NONE"\r\n")

#define LS_TRACE_FAILED(fmt, ...) LS_Trace(LS_LOG_FAILED,"\r"LIGHT_RED,DBG_TAG, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__);
#define LS_TRACE_INFO(fmt, ...) LS_Trace(LS_LOG_INFO,"\r"YELLOW,DBG_TAG, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__);
#define LS_TRACE_DEBUG(fmt, ...) LS_Trace(LS_LOG_DEBUG,"\r"GREEN,DBG_TAG, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__);
#define LS_TRACE_ERROR(fmt, ...) LS_Trace(LS_LOG_ERROR,"\r"RED,DBG_TAG, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__);


#define _CALL_ERROR()                       \
do {                                    \
    LS_TRACE_ERROR("(Call Error Handler)"); \
    error_handler();                    \
} while (0)



#define LS_RETURN_NOT(express,fmt, ...) \
do \
{\
	if(!(express)) \
	{ \
		LS_TRACE_FAILED(fmt, ##__VA_ARGS__); \
		return ; \
	} \
}while(0)


#define LS_RETURN(express, ret, fmt, ...) \
do \
{\
	if(!(express)) \
	{ \
		LS_TRACE_FAILED(fmt, ##__VA_ARGS__); \
		return (ret); \
	} \
}while(0)


#define LS_RETURN_NOLOG(express, ret, fmt, ...) \
do \
{\
	if(!(express)) \
	{ \
		LS_TRACE_FAILED(fmt, ##__VA_ARGS__); \
		return (ret); \
	} \
}while(0)



#define LS_GOTO(express, ret_key, ret, go, fmt, ...) \
do \
{\
	if(!(express)) \
	{ \
		LS_TRACE_FAILED(fmt, ##__VA_ARGS__); \
		ret_key = (ret); \
		goto go; \
	} \
}while(0)


#define LS_GOTO_NOLOG(express, ret_key, ret, go, fmt, ...) \
do \
{\
	if(!(express)) \
	{ \
		LS_TRACE_FAILED(fmt, ##__VA_ARGS__); \
		ret_key = (ret); \
		goto go; \
	} \
}while(0)


#define LS_BREAK(express, ret_key, ret, fmt, ...) \
if(!(express)) \
{ \
	LS_TRACE_FAILED(fmt, ##__VA_ARGS__); \
	ret_key = (ret); \
	break; \
}



//定义malloc 需要时可以扩展内存检测
#define ls_malloc(size) 			malloc(size)
#define ls_free(addr)				free(addr);addr= NULL


#define LS_ARRAY_SIZE(X)			(sizeof(X)/sizeof(X[0]))

#endif /**/